package com.tj.collection.db.service.impl;

import com.fqgj.common.api.Page;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.EntityUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.tj.collection.bean.SystemConstants;
import com.tj.collection.db.admin.dao.AuthAdminRoleDAO;
import com.tj.collection.db.admin.dao.AuthMenuDAO;
import com.tj.collection.db.admin.dao.AuthRoleDAO;
import com.tj.collection.db.admin.dao.AuthRoleMenuDAO;
import com.tj.collection.db.admin.entity.AuthAdminRoleEntity;
import com.tj.collection.db.admin.entity.AuthMenuEntity;
import com.tj.collection.db.admin.entity.AuthRoleEntity;
import com.tj.collection.db.admin.entity.AuthRoleMenuEntity;
import com.tj.collection.db.domain.Role;
import com.tj.collection.db.enums.RoleKeyEnum;
import com.tj.collection.db.service.AdminRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2017/3/14
 * Time: 下午1:17
 */
@Service
public class AdminRoleServiceImpl implements AdminRoleService {

    public static final Log LOGGER = LogFactory.getLog(AdminRoleServiceImpl.class);

    @Autowired
    private AuthAdminRoleDAO authAdminRoleDAO;

    @Autowired
    private AuthRoleDAO authRoleDAO;

    @Autowired
    private AuthRoleMenuDAO authRoleMenuDAO;

    @Autowired
    private AuthMenuDAO authMenuDAO;

    @Override
    public Boolean add(Role role) {
        AuthRoleEntity authRoleEntity = new AuthRoleEntity();
        authRoleEntity.setName(role.getName());
        authRoleEntity.setDeleted(false);
        authRoleEntity.setDescription(role.getDescription());
        authRoleEntity.setMerchantCode(role.getMerchantCode());

        return authRoleDAO.save(authRoleEntity) > 0;
    }

    @Override
    public Boolean addRoleAndMenu(Role role, List<Long> menuIds) {

        //添加角色
        AuthRoleEntity authRoleEntity = new AuthRoleEntity();
        authRoleEntity.setName(role.getName());
        authRoleEntity.setDeleted(false);
        authRoleEntity.setDescription(role.getDescription());
        authRoleEntity.setMerchantCode(role.getMerchantCode());
        authRoleDAO.save(authRoleEntity);
        //关联角色和菜单
        if (CollectionUtils.isEmpty(menuIds)) {
            return false;
        }
        Long roleId = authRoleEntity.getId();
        List<Long> roleIds = new ArrayList<>();
        roleIds.add(roleId);
        List<AuthRoleMenuEntity> authRoleMenuEntityList = authRoleMenuDAO.getListByRoleIds(roleIds);
        if (CollectionUtils.isNotEmpty(authRoleMenuEntityList)) {
            authRoleMenuDAO.deleteByRoleId(roleId);
        }
        for (Long menuId : menuIds) {
            AuthRoleMenuEntity authRoleMenuEntity = new AuthRoleMenuEntity();
            authRoleMenuEntity.setRoleId(roleId);
            authRoleMenuEntity.setMenuId(menuId);
            authRoleMenuDAO.save(authRoleMenuEntity);
        }
        return true;
    }

    /**
     * 角色菜单同步
     * 只同步通用菜单
     *
     * @param roleKey
     * @param sourceMerchantCode
     * @param targetMerchantCode
     * @return
     */
    @Override
    public Boolean syncRoleAndMenu(String roleKey, String sourceMerchantCode, String targetMerchantCode) {
        Long sourceRoleId = authRoleDAO.getRoleIdByRoleKey(roleKey, sourceMerchantCode);
        if (sourceRoleId == null) {
            LOGGER.info("syncRoleAndMenu,sourceRoleId为空1,roleKey:{},sourceMerchantCode:{},targetMerchantCode:{}", roleKey, sourceMerchantCode, targetMerchantCode);
            return false;
        }
        List<AuthRoleMenuEntity> authRoleMenuEntityList = authRoleMenuDAO.getListByRoleIds(Arrays.asList(sourceRoleId));
        if (authRoleMenuEntityList == null || authRoleMenuEntityList.size() == 0) {
            LOGGER.info("syncRoleAndMenu,authRoleMenuEntityList为空2,roleKey:{},sourceMerchantCode:{},targetMerchantCode:{}", roleKey, sourceMerchantCode, targetMerchantCode);
            return true;
        }
        List<Long> menuIds = authRoleMenuEntityList.stream().map(AuthRoleMenuEntity::getMenuId).collect(Collectors.toList());
        List<AuthMenuEntity> authMenuEntityList = authMenuDAO.getListByIds(menuIds);
        if (authMenuEntityList == null || authMenuEntityList.size() == 0) {
            LOGGER.info("syncRoleAndMenu,authMenuEntityList为空3,roleKey:{},sourceMerchantCode:{},targetMerchantCode:{}", roleKey, sourceMerchantCode, targetMerchantCode);
            return true;
        }
        //DHANADHANV6 的商户是自己家的 不需要剔除菜单
        if (!SystemConstants.DHANADHANV6.equals(targetMerchantCode)) {
            authMenuEntityList = authMenuEntityList.stream().filter(item -> item.getMenuType() == 1).collect(Collectors.toList());
        }
        if (authMenuEntityList == null) {
            LOGGER.info("syncRoleAndMenu,authMenuEntityList为空4,roleKey:{},sourceMerchantCode:{},targetMerchantCode:{}", roleKey, sourceMerchantCode, targetMerchantCode);
            authMenuEntityList = new ArrayList<>();
        }
        List<Long> waitSyncMenuIds = authMenuEntityList.stream().map(AuthMenuEntity::getId).collect(Collectors.toList());

        Long targetRoleId = authRoleDAO.getRoleIdByRoleKey(roleKey, targetMerchantCode);
        if (targetRoleId == null) {
            LOGGER.info("syncRoleAndMenu,targetRoleId为空5,roleKey:{},sourceMerchantCode:{},targetMerchantCode:{}", roleKey, sourceMerchantCode, targetMerchantCode);
            return false;
        }

        List<AuthMenuEntity> allMenuList = authMenuDAO.getAllList();
        Map<Long, AuthMenuEntity> allMenuMap = EntityUtils.makeEntityMap(allMenuList, "id");

        List<AuthRoleMenuEntity> authRoleMenuEntityList2 = authRoleMenuDAO.getListByRoleIds(Arrays.asList(targetRoleId));
        //删除多余菜单
        for (AuthRoleMenuEntity authRoleMenuEntity : authRoleMenuEntityList2) {
            AuthMenuEntity menuEntity = allMenuMap.get(authRoleMenuEntity.getMenuId());
            if (menuEntity != null && menuEntity.getMenuType() != null && menuEntity.getMenuType() == 2) {
                LOGGER.info("自定义菜单不同步,跳过,menuID:{}", menuEntity.getId());
                continue;
            }
            if (!waitSyncMenuIds.contains(authRoleMenuEntity.getMenuId())) {
                authRoleMenuDAO.deleteById(authRoleMenuEntity.getId());
            }
        }
        //重新查询目标商户角色菜单权限
        authRoleMenuEntityList2 = authRoleMenuDAO.getListByRoleIds(Arrays.asList(targetRoleId));
        List<Long> menuIds2 = authRoleMenuEntityList2.stream().map(AuthRoleMenuEntity::getMenuId).collect(Collectors.toList());
        //补充新菜单
        for (AuthMenuEntity authMenuEntity : authMenuEntityList) {
            if (!menuIds2.contains(authMenuEntity.getId())) {
                AuthRoleMenuEntity authRoleMenuEntity = new AuthRoleMenuEntity();
                authRoleMenuEntity.setRoleId(targetRoleId);
                authRoleMenuEntity.setMenuId(authMenuEntity.getId());
                authRoleMenuDAO.save(authRoleMenuEntity);
            }
        }

        return true;
    }

    @Override
    public List<Role> searchRoleList(String roleName, Page page, String merchantCode) {
        List<AuthRoleEntity> entities = authRoleDAO.getListByNameAndPage(roleName, page, merchantCode);
        if (CollectionUtils.isEmpty(entities)) {
            return null;
        }

        List<Role> roleList = new ArrayList<>();
        for (AuthRoleEntity authRoleEntity : entities) {
            Role role = new Role(authRoleEntity.getId(), authRoleEntity.getName(), authRoleEntity.getDescription(), authRoleEntity.getMerchantCode());
            role.setRoleKey(authRoleEntity.getRoleKey());
            roleList.add(role);
        }

        return roleList;
    }

    @Override
    public Boolean update(Role role) {
        AuthRoleEntity authRoleEntity = authRoleDAO.selectById(role.getRoleId());
        if (authRoleEntity == null) {
            return false;
        }

        authRoleEntity.setName(role.getName());
        authRoleEntity.setDescription(role.getDescription());
        return authRoleDAO.update(authRoleEntity) > 0;
    }

    @Override
    public List<Long> getRoleIdsByAdminId(Long adminId) {
        List<AuthAdminRoleEntity> authAdminRoleEntityList = authAdminRoleDAO.getListByAdminId(adminId);
        if (authAdminRoleEntityList == null) {
            return null;
        }

        return authAdminRoleEntityList.parallelStream().map(AuthAdminRoleEntity::getRoleId).collect(Collectors.toList());
    }

    @Override
    public List<Role> getRolesByAdminId(Long adminId) {
        List<AuthAdminRoleEntity> authAdminRoleEntityList = authAdminRoleDAO.getListByAdminId(adminId);
        if (authAdminRoleEntityList == null) {
            return null;
        }

        List<Role> roleList = new ArrayList<>();
        for (AuthAdminRoleEntity authAdminRoleEntity : authAdminRoleEntityList) {
            AuthRoleEntity authRoleEntity = authRoleDAO.selectById(authAdminRoleEntity.getRoleId());
            Role role = new Role(authRoleEntity.getRoleKey(), authRoleEntity.getId(), authRoleEntity.getName(), authRoleEntity.getDescription(), authRoleEntity.getMerchantCode());
            roleList.add(role);
        }
        return roleList;
    }

    @Override
    public Boolean addRoleToAdmin(Long adminId, List<Long> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return false;
        }

        if (CollectionUtils.isNotEmpty(getRoleIdsByAdminId(adminId))) {
            authAdminRoleDAO.deleteByAdminId(adminId);
        }

        for (Long roleId : roleIds) {
            AuthAdminRoleEntity authAdminRoleEntity = new AuthAdminRoleEntity();
            authAdminRoleEntity.setAdminId(adminId);
            authAdminRoleEntity.setRoleId(roleId);

            authAdminRoleDAO.save(authAdminRoleEntity);
        }

        return true;
    }

    @Override
    public Boolean addOneRoleToAdmin(Long adminId, Long roleId) {
        if (adminId == null || roleId == null) {
            return false;
        }
        List<AuthAdminRoleEntity> authAdminRoleEntityList = authAdminRoleDAO.getListByAdminId(adminId);
        if (CollectionUtils.isEmpty(authAdminRoleEntityList)
                || !(authAdminRoleEntityList.stream().map(AuthAdminRoleEntity::getRoleId).collect(Collectors.toList())).contains(roleId)) {
            AuthAdminRoleEntity authAdminRoleEntity = new AuthAdminRoleEntity();
            authAdminRoleEntity.setAdminId(adminId);
            authAdminRoleEntity.setRoleId(roleId);
            authAdminRoleDAO.save(authAdminRoleEntity);
        }
        return true;
    }

    /**
     * 获取信审人员的角色id
     *
     * @param roleKeyEnum
     * @return
     */
    @Override
    public Long getRoleIdForAuditor(RoleKeyEnum roleKeyEnum, String merchantCode) {
        return authRoleDAO.getRoleIdByRoleKey(roleKeyEnum.getType(), merchantCode);
    }

    @Override
    public Long getRoleIdByRoleKey(RoleKeyEnum roleKeyEnum, String merchantCode) {
        return authRoleDAO.getRoleIdByRoleKey(roleKeyEnum.getType(), merchantCode);
    }

    @Override
    public List<Long> getRoleIdByRoleKeyList(List<RoleKeyEnum> roleKeyEnumList, String merchantCode) {
        return authRoleDAO.getRoleIdByRoleKeyList(this.getTypes(roleKeyEnumList), merchantCode);
    }

    /**
     * 判断是否存在指定角色
     *
     * @param adminId
     * @param roleKeyEnum
     * @param merchantCode
     * @return
     */
    @Override
    public boolean isContainsRoleKey(Long adminId, RoleKeyEnum roleKeyEnum, String merchantCode) {
        List<Role> roleList = getRolesByAdminId(adminId);
        if (CollectionUtils.isEmpty(roleList)) {
            return false;
        }
        for (Role role : roleList) {
            if (Objects.equals(merchantCode, role.getMerchantCode()) && roleKeyEnum.getType().equals(role.getRoleKey())) {
                return true;
            }
        }
        return false;
    }

    private List<String> getTypes(List<RoleKeyEnum> roleKeyEnumList) {
        List<String> types = new ArrayList<>();
        for (RoleKeyEnum roleKeyEnum : roleKeyEnumList) {
            types.add(roleKeyEnum.getType());
        }
        return types;
    }

    /**
     * 获取超级管理员的角色id
     *
     * @return
     */
    @Override
    public Long getRoleIdForSuperAdmin(String merchantCode) {
        return authRoleDAO.getRoleIdByRoleKey(RoleKeyEnum.SUPERADMIN.getType(), merchantCode);
    }

    @Override
    public List<Long> getSuperAndAuditManagerRoleIds(String merchantCode) {
        List<String> keyList = new ArrayList<>();
        keyList.add(RoleKeyEnum.SUPERADMIN.getType());
        return authRoleDAO.getRoleIdByRoleKeyList(keyList, merchantCode);
    }

    /**
     * @param roleId 角色ID
     * @return
     */
    @Override
    public List<Long> getAdminIdListByRoleId(Long roleId) {
        return authAdminRoleDAO.getAdminIdListByRoleId(roleId);
    }

    /**
     * @param roleIdList
     * @return
     */
    @Override
    public List<Long> getAdminIdListByRoleIdList(List<Long> roleIdList) {
        return authAdminRoleDAO.getAdminIdListByRoleIdList(roleIdList);
    }

    /**
     * 校验管理员的角色
     *
     * @param adminId 管理员
     * @param roleIds 角色id
     * @return
     */
    @Override
    public Boolean checkAdminRole(Long adminId, List<Long> roleIds) {
        return authAdminRoleDAO.checkAdminRole(adminId, roleIds);
    }

}
